<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href="Doc.css" rel="stylesheet"/>
<title>TreeGrid - Server paging with DLL/SO</title>
</head>
<body>
<div class="Doc">


<h1>TreeGrid server library v<span style="color:blue;">3.6</span></h1>
<p>TreeGrid documentation</p>

<b>TreeGrid server</b> is helper library for very large grids to use server side <a href="PagingServer.htm">paging</a> or <a href="PagingServer.htm#ChildPaging">child paging</a>. You can, but <b>you need not use it</b> for server paging.<br />
<b>TreeGrid server</b> is dynamic link library (<b>.dll</b> for <b>Windows</b> and <b>.so</b> for <b>Linux</b>).<br /> 
It is written in C++ and is very <b>fast</b> and <b>not memory consuming</b>.<br />
Works upon XML data and provides intrinsic functionality for <b><a href="PagingServer.htm">server side paging</a></b>, <b>sorting</b>, <b>filtering</b>, <b>grouping</b>, <b>calculations</b> and <b>updates</b>.<br />
Input data are the same as in client application (XML with defaults, XML with grid layout and XML with data). DLL exports all functions needed to support server paging and updating TreeGrid.<br />
TreeGrid server can be used in <b>ASP.NET</b>, <b>Java servlets</b> / <b>JSP</b>, <b>PHP</b> or any server script environment that supports using dynamic link libraries.<br />
All input / output data are in XML <b><a href="DataFormats.htm#InternalFormat">Internal format</a></b>.<br />
TreeGrid server is <b>thread safe</b>.<br /> 
TreeGrid server does not care about sharing data among clients. <i>Every client must have own instance of server grid,</i> because of their own sorting and filter settings. If you want to support write access for more clients, you must call <a href="#Save">Save</a> method for all opened grid (in group) with the same changes.<br />
Default rounding precision of all numbers in TreeGrid server is 4 digits. It can be changed by <tt>&lt;Cfg <b>Precision</b>=''/></tt>, available values are 0 - 9.<br />

<!-----------------------  Compatibility with TreeGrid component  ------------------------>
<a name="Compatibility"></a>
<h3>Compatibility with TreeGrid component</h3>

<i>TreeGrid server library is compatible with TreeGrid component v6.0+ <u><b>except</b></u>:</i><br /><br />

It supports only <a href="DataFormats.htm#InternalFormat">Internal format</a> of XML input / output data. You must set <tt>&lt;treegrid *_Format='<b>Internal</b>'></tt>, where * is Data, Page, Upload, Export, Check.<br />
It supports only some formulas syntax and few functions, see <a href="#Calculations">Calculations section</a>.<br />
It does <u>not</u> support advanced <b>CalcOrder</b> - it does <u>not</u> support wildcards in CalcOrder attribute and <s><b>CalcOrderX</b></s> attributes and also &lt;<s>Cfg CalcOrder</s>> attribute (uses only &lt;I CalcOrder).<br />
Up to <b>three sort columns</b> are supported.<br />
Attributes <b>LocaleCompare</b>, <b>CaseSensitive</b>, <b>WhiteChars</b>, <b>CharCodes</b>  and <b>GroupSole</b>, <b>GroupSingle</b>, <b>GroupEmpty</b> are supported only in &lt;C> tag.<br />
Other default cols &lt;D> than <tt>&lt;D Name="C"/></tt> are ignored.<br />
Only base types (Bool, Int, Float, Date, Enum, Radio, Text, Lines) are sorted and filtered as expected.<br />
<div class="L1">
  Bool, Int, Enum, Radio and Date are integers, Float are floats and other types are strings.<br />
  To sort or filter extended types like <b>Link</b>, you should use cell attributes <a href="Sort.htm#CellSortValue">SortValue</a>, <a href="Sort.htm#CellSortDescValue">SortDescValue</a> and <a href="Filter.htm#CellFilterValue">FilterValue</a>.<br />
  Enum type should be set as integer not string and <s><a href="TypeEnum.htm#CEnumKeys">EnumKeys</a></s> attribute is ignored.<br />
</div>
It uses only basic row identification by unique id, so extended id attributes <s><b>IdNames</b></s>, <s><b>FullId</b></s>, <s><b>AppendId</b></s>, <s><b>IdCompare</b></s> <u>must not</u> be used.<br />
It uses date time values as integers (number of milliseconds since 1/1/1970 00:00:00) for input and output. You also <u>must not</u> use attribute &lt;Cfg <s><b>DateStrings</b></s>>. See also <a href="TypeDate.htm#FormatGMT">GMT</a> attribute.<br />
Attribute <s><a href="CellSpan.htm#ISortSpan">SortSpan</a></s> is ignored.<br />
Attribute <a href="CellBasics.htm#CellRange">Range</a> is used only in filter rows. In all other cells is the value treated as simple string.<br />
<s><b>Search</b></s> and <s><b>advanced filters</b></s> are not supported yet.<br />
The <b>filter</b> rows (&lt;<u>Filter</u>>) must have set <b>id</b> attribute if there are more filter rows.<br />

<!-----------------------  Using TreeGrid server  ------------------------>
<a name="Using"></a>
<h3>Using TreeGrid server</h3>

All functions are exported as  extern <tt><b>"C" __declspec(dllexport) ... __stdcall</b></tt>  (standard C++ exports).<br /> 
All strings parameters are in <b>unicode</b>. For all string handling functions there are functions ends with "<b style="color:blue;">A</b>" using <b>UTF8</b> strings (CreateGrid => CreateGridA).<br />
Input XML strings can be standard XML "<...></...>" or entity encoded "&amp;lt; ... &amp;gt;&amp;lt;/...&amp;gt;"<br />

<!--  ASP.NET C#  -->
<a name="ASPNETC"></a>
<h5>ASP.NET C#</h5>
Declare all needed functions with DllImport attribute and static extern keywords:<br />
<tt><b>DllImport("TreeGrid.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]</b></tt><br />
<tt><b>public static extern</b> <i>return_type function_name( ... parameters ...);</i></tt><br />
If you want to place TreeGrid.dll anywhere else then in Windows/System32 directory you need to load it by function <b>LoadLibrary</b> before any its method is called.<br />
To use <b>LoadLibrary</b> you must declare it in the same manner as TreeGrid functions:<br />
<tt>[DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern IntPtr LoadLibrary(string lpFileName);</tt><br />
Supported <b>.NET 1.0, 1.1, 2.0, ...</b><br /><br />

<u><i>Whole declaration:</i></u><br />
<i>[DllImport("kernel32.dll", CharSet = CharSet.Auto)]</i><br />
static extern IntPtr LoadLibrary(string lpFileName);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern int CreateGrid(string Data, string Layout, string Defaults, string Text, string Bonus, string Bonus2);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern int UpdateGrid(int Index, string Bonus);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern int FindGrid(string Cfg);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern int FindGrids(IntPtr Indexes, int Max, string Cfg, int Seconds, int Type);<br />
public static int FindGrids(ref int []Indexes, int Max, string Cfg, int Seconds, int Type)&#123;<br />
   <div class="L1">
   return FindGrids(GCHandle.Alloc(Indexes,GCHandleType.Pinned).AddrOfPinnedObject(),Max,Cfg,Seconds,Type);<br />
   }<br />
   </div>
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetSession(string Cfg);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetGridSession(int Index);<br />
public static extern int DeleteGrid(int Index);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern void Clear();<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern string GetBody(int Index, string Cfg);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern string GetPage(int Index, string Cfg);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern string GetExport(int Index, string Cfg);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern int Save(int Index, string Input);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern int SaveEx(int Index, string Input, int Type);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br /> 
public static extern int SaveToFile(int Index, string FileName, int Type);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetData(int Index);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string LastError();<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetLastId(int Index);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetChanges(int Index, int Type);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern string GetCells (int Index, string Row, string Col, int Type, string Param);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern int SetDebug(int Index, string FileName);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern int SetGridLocale(int Index, string Locale);<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern void EnterRead( );<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern void LeaveRead( );<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern void EnterWrite( );<br />
<i>[DllImport("TreeGrid.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]</i><br />
public static extern void LeaveWrite( );<br />

<!--  ASP.NET VB  -->
<a name="ASPNETVB"></a>
<h5>ASP.NET VB</h5>
Declare all needed functions:<br />
<tt><b>Declare Unicode Function function_name Lib "TreeGrid.dll" (... parameters ...) As</b> <i>return_type</i></tt><br />
If you want to place TreeGrid.dll anywhere else then in Windows/System32 directory you need to load it by function <b>LoadLibrary</b> before any its method is called.<br />
To use <b>LoadLibrary</b> you must declare it in the same manner as TreeGrid functions:<br />
<tt>Declare Auto Function LoadLibrary Lib "kernel32.dll" (ByVal lpFileName As String) As IntPtr</tt><br />
Supported <b>.NET 1.0, 1.1, 2.0, ...</b><br /><br />

<u><i>Whole declaration:</i></u><br />
Declare Auto Function LoadLibrary Lib "kernel32.dll" (ByVal lpFileName As String) As IntPtr<br />
Declare Unicode Function CreateGrid Lib "TreeGrid.dll" (ByVal Data As String, ByVal Layout As String, ByVal Defaults As String, ByVal Text As String, _<br />
  <div class="L1">ByVal Bonus As String, ByVal Bonus2 As String) As Integer</div>
Declare Unicode Function UpdateGrid Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Bonus As String) As Integer<br />
Declare Unicode Function FindGrid Lib "TreeGrid.dll" (ByVal Cfg As String) As Integer<br />
Declare Unicode Function FindGrids Lib "TreeGrid.dll" (ByVal Indexes As IntPtr, ByVal Max As Integer, ByVal Cfg As String, ByVal Seconds As Integer, _<br />
  <div class="L1">ByVal Type As Integer) As Integer</div>
Public Function FindGrids(ByVal Indexes() As Integer, ByVal Max As Integer, ByVal Cfg As String, ByVal Seconds As Integer, ByVal Type As Integer) As Integer<br />
  <div class="L1">Return FindGrids(GCHandle.Alloc(Indexes, GCHandleType.Pinned).AddrOfPinnedObject(), Max, Cfg, Seconds, Type)</div>
End Function<br />
Declare Unicode Function GetSession Lib "TreeGrid.dll" (ByVal Cfg As String) As String<br />
Declare Unicode Function GetGridSession Lib "TreeGrid.dll" (ByVal Index As Integer) As String<br />
Declare Unicode Function DeleteGrid Lib "TreeGrid.dll" (ByVal Index As Integer) As Integer<br />
Declare Unicode Sub Clear Lib "TreeGrid.dll" ()<br />
Declare Unicode Function GetBody Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Cfg As String) As String<br />
Declare Unicode Function GetPage Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Cfg As String) As String<br />
Declare Unicode Function GetExport Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Cfg As String) As String<br />
Declare Unicode Function Save Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Input As String) As Integer<br />
Declare Unicode Function SaveEx Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Input As String, ByVal Type As Integer) As Integer<br />
Declare Unicode Function SaveToFile Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal FileName As String, ByVal Type As Integer) As Integer<br />
Declare Unicode Function GetData Lib "TreeGrid.dll" (ByVal Index As Integer) As String<br />
Declare Unicode Function GetLastId Lib "TreeGrid.dll" (ByVal Index As Integer) As String<br />
Declare Unicode Function LastError Lib "TreeGrid.dll" () As String<br />
Declare Unicode Function GetChanges Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Type As Integer) As String<br />
Declare Unicode Function GetCells Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Row As String, ByVal Col As String, ByVal Type As Integer, _<br />
  <div class="L1">ByVal Param As String) As String</div>
Declare Unicode Function SetDebug Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal FileName As String) As Integer<br />
Declare Unicode Function SetGridLocale Lib "TreeGrid.dll" (ByVal Index As Integer, ByVal Locale As String) As Integer<br />
Declare Unicode Sub EnterRead Lib "TreeGrid.dll" ()<br />
Declare Unicode Sub LeaveRead Lib "TreeGrid.dll" ()<br />
Declare Unicode Sub EnterWrite Lib "TreeGrid.dll" ()<br />
Declare Unicode Sub LeaveWrite Lib "TreeGrid.dll" ()<br />

<!--  PHP  -->
<a name="PHP"></a>
<h5>PHP</h5>
In PHP TreeGrid.dll/so works as <b>PHP extension</b>.<br /> 
Copy it to you PHP extensions directory and add to your <b>php.ini</b> to main [PHP] section the line <tt><b>extension=TreeGrid.dll</b></tt> on Windows or <tt><b>extension=TreeGrid.so</b></tt> on Linux.<br />
<i><b style="color:red;">! TreeGrid.dll/so must not be the first PHP extension loaded!</b> So ensure that in <b>php.ini</b> is at least one active line <tt><b>extension=xxx</b></tt> before the <tt><b>extension=TreeGrid.dll/so</b></tt>.</i><br /><br />

TreeGrid.dll/so PHP extension is compatible with PHP versions <b>5.0</b> - <b>5.5</b>. Both PHP <b>thread-safe</b> / <b>thread-unsafe</b> versions. Only PHP <b>non-debug</b> version.<br />
It should work also in future releases, but because of pure amateurism of PHP authors there is no insurance that it will do. We sometimes check and update the extension to be compatible with new PHP releases. If you encounter that TreeGrid.dll/so does not work in PHP release other that listed above let us know to update the TreeGrid.dll/so.<br /><br />

<b>Windows</b><br />
The TreeGrid.dll library is intended to be persistently placed in memory. Therefore you should run the PHP engine as <b>ISAPI</b> service and <b>not CGI</b> application.<br />
If you installed PHP by windows installer, the PHP is configured by default to run as <b>CGI</b> application. Check <b>Install.txt</b> file in your PHP directory how to change PHP to run as <b>ISAPI</b> service. For example WinXP and IIS - just open IIS configuration, choose your virtual web server directory, select <i><b>Properties->Virtual Directory->Configuration->Mappings</b></i>, select <i><b>.php Extension</i></b> and click <i><b>Edit</b></i> button and browse for <b><i>Executable</i> php5isapi.dll</b>.<br /><br />

TreeGrid.dll will work also with PHP as <b>CGI</b> application, but after every page processing the DLL is unloaded from memory and all grid instances are deleted, so in this case you need always to save all grid instances to disk and load them when processing new command. It can slow down using TreeGrid.dll/so.<br /><br />

Remember, if PHP runs as <b>ISAPI</b> service and you do some changes in <b>php.ini</b>, you usually need to restart whole web server service, for example for IIS you need often to restart <b>IIS Admin</b> service from services dialog. Also remember, that PHP running as <b>ISAPI</b> can have another relative path, so you should set in <b>php.ini</b> the <b>extension_dir</b> to absolute path where to search PHP extensions.<br /><br />

<b>Using</b><br />
Call TreeGrid function like other PHP functions, for example<br />  
<div class="L1"><tt>$grid = TGCreateGrid($DataFile,$LayoutsFile,$TextFile,$DefaultsFile,"","");</tt></div>
<b style="color:red;">!</b> PHP does not use Unicode, thus you must all strings encode in <b>UTF8</b>. But call TreeGrid functions <u>without</u> prefix "A" (CreateGrid).<br /> 
<b style="color:red;">!</b> Remember, if PHP on Windows is simple CGI application without any state memory, after finishing request unloads all resources including TreeGrid.dll. Therefore you must not store indexes between requests, but you must store whole data to file (by SaveToFile) or database (by GetData).<br />
<b style="color:red;">!</b> All TreeGrid function names in PHP starts with prefix "<b style="color:red;">TG</b>".<br /><br />

<u><i>Whole declaration:</i></u><br />
There is no need for external declaration of TreeGrid functions in PHP.<br /> 
But remember all function names start with prefix "<b style="color:red;">TG</b>".<br />

<!--  JSP Java  -->
<a name="JSPJava"></a>
<h5>JSP Java</h5>
In <b>Java</b> there is used <b>JNI</b> (Java Native Interface) in provided package <b>TreeGrid</b>, class <b>Server</b>. Therefore you need create an instance of the <b>TreeGrid.Server</b> and use its methods.<br />
First copy <b style="color:blue;">TreeGrid.jar</b> file (located in <a href="TreeGrid.jar">/Server/Jsp</a> directory of your TreeGrid distribution) to your JRE installed optional packages, usually located at "&lt;java-home>\lib\ext".<br />
You can copy <b style="color:blue;">TreeGrid.dll</b> file (located in <a href="TreeGrid.dll">/Server</a> directory of your TreeGrid distribution) to your JRE BIN directory, usually located at "&lt;java-home>\bin" or "&lt;java-home>\lib\ext\x86". &lt;java-home> is directory where JRE is installed or JDK/jre. To run TreeGrid examples it is not needed.<br />
Now you can in your code create TreeGrid.Server instance by<br /> 
<div class="L1"><tt>TreeGrid.Server TS = new TreeGrid.Server();</tt></div>
If you have not copied TreeGrid.dll to JRE BIN directory, you must specify its path and name as parameter:<br /> 
<div class="L1"><tt>TreeGrid.Server TS = new TreeGrid.Server ("TreeGrid_distribution_path/Server/TreeGrid");</tt></div> 
Now you can call any TreeGrid server function as method of the TS instance. <tt>int G = T.CreateGrid( ... );</tt><br />
You can test if DLL was successfully loaded by static <b>TreeGrid.Server.Loaded</b> property. DLL is loaded when creating the first instance of TreeGrid.Server. If DLL loading has failed, the static String <b>TreeGrid.Server.DllError</b> contains the exception's message string.<br />
Supported any <b>Java</b> version with <b>JNI</b>.<br /><br />

<u><i>Whole declaration:</i></u>
There is no need for external declaration of TreeGrid functions in Java - it is already declared in <b>TreeGrid.jar</b> in object <b>TreeGrid.Server</b>.<br />

<!-----------------------  TreeGrid server concepts  ------------------------>
<a name="Concepts"></a>
<h3>TreeGrid server concepts</h3>

<!--  Basics  -->
<a name="Basics"></a>
<h5>Basics</h5>
a) You have stored your data somewhere on disk or in database.<br /><br /> 

b) When first request to this data arrives, you need to read all you data and convert it to the TreeGrid XML internal format and create TreeGrid instance from this data by calling <a href="#CreateGrid">CreateGrid</a>. And fulfill the request by calling <a href="#GetPage">GetPage</a>, <a href="#GetBody">GetBody</a>, <a href="#Save">Save</a> or <a href="#GetExport">GetExport</a> method of the created instance.<br />
<i>This means that every client has its own grid instance on server, because every client can have its own individual state of sorting, filtering or grouping.</i><br /><br />

c) For next requests you have to resolve the TreeGrid instance the request belongs (by URL, by some user parameter, by &lt;<b>IO</b> <a href="DataCommunication.htm#IOSession">Session</a>> attribute or by any you custom way, see <a href="#FindGrid">FindGrid</a> and <a href="#FindGrids">FindGrids</a> function) and fulfill the request by calling <a href="#GetPage">GetPage</a>, <a href="#GetBody">GetBody</a>, <a href="#Save">Save</a> or <a href="#GetExport">GetExport</a> method of the found instance.<br /><br />

d) After every <a href="#RequestUpdate">Update</a> request you will save data changes to grid instance by <b><a href="#Save">Save</a></b> method as mentioned in c).<br />
But you need to save changes also your original data store (database, file, etc.) by parsing the request XML and updating to your original store. See <a href="DataUpload.htm#XML">XML structure - upload</a>.<br /><br />

The &lt;<b>IO</b> <a href="DataCommunication.htm#IOSession">Session</a>> can be modified by CreateGrid, UpdateGrid and GetBody if the sent xml contains this attribute set.<br /><br />

<i>For use TreeGrid server you have to separate data (rows) that can be changed and updated from layout (columns, other settings). Layout is usually in static XML file, which is regenerated only when data layout changes, for example a column is added. Remember, <a href="#GetBody">GetBody</a> returns data only, not layout.</i><br />

<!--  Creating instance  -->
<a name="Creating"></a>
<h5>Creating instance</h5>
Create TreeGrid instance from data in files or in strings (<b><a href="#CreateGrid">CreateGrid</a></b>). This data must contain all data for the session.<br />
Instance is created in memory and you will get handle (<b>Index</b>) to it.<br /> 
The instance stays in memory until you delete it by <b><a href="#DeleteGrid">DeleteGrid</a></b> or <b><a href="#Clear">Clear</a></b> function or until TreeGrid server is not <b>unloaded</b>. TreeGrid server is unloaded for example if the server side script is restarted. In this case you need to save data from memory to persistent storage (disk (by <b><a href="#SaveToFile">SaveToFile</a></b>) or database (by <b><a href="#GetData">GetData</a></b>)) and re-create it when processing next request.<br />
<i>On some systems (for example in PHP as CGI  on Windows) is TreeGrid server unloaded immediately after client’s request is fulfilled, so in this case you must always save changed data to persistent storage as disk or database and create grid again when processing next request.</i><br />
Particular instances are independent on the others. You can have more instances of the same data or different data. Count of instances is restricted by available memory only. Remember, the memory consumed by instance is usually similar to input size of input XML data in ASCII or 2/3 if they are in unicode. But always depends on data structure.<br />
You should also know that grouping data can allocate significantly more memory, depending on count of groups, but it can double or even triple memory allocation when many groups are generated.<br />

<!--  Finding instance  -->
<a name="Finding"></a>
<h5>Finding instance</h5>
How to find instance that the request belongs to?<br /> 

<!--Session-->
<a name="FindingSession"></a>
<h6>Session</h6>
The easiest way is to use TreeGrid built-in Session concept. When grid instance is created on server, it gets its unique Session attribute. This Session attribute is sent to client in GetBody request. And client in every future request will send this Session attribute within the request. You can control how client will store its Session by &lt;Cfg <a href="DataCommunication.htm#CfgSaveSession">SaveSession</a>/> attribute. To get grid instance with appropriate Session call <a href="#FindGrid">FindGrid </a>with the whole request XML.<br />
When you get request with Session no longer exist on server (FindGrid returned -1) you have to create new instance (for GetBody request) or return error for other request.<br />

<!--More instances by custom attribute-->
<a name="FindingMore"></a>
<h6>More instances by custom attribute</h6>
When you want to permit write access to the grid data and read access for more clients, you will need, when saving, to get all grid instances with appropriate table and save changes to them all. To get some instances you need to mark them when creating by setting some your custom attribute in &lt;Cfg> tag and when needed call FindGrids to get all the instances according to the custom attribute. For example:<br />
Create grids like: <tt>index = CreateGrid("...","...","...","...","...","&lt;Grid>&lt;Cfg Ident='MyGridX1'/>&lt;/Grid>");</tt><br />
And get all the instances of MyGridX1 by: <tt>count = FindGrids(array, 100, "&lt;Grid>&lt;Cfg Ident='MyGridX1'/>&lt;/Grid>",0,0);</tt><br />

<!--Custom way-->
<a name="FindingCustom"></a>
<h6>Custom way</h6>
You can also identify the grid by any your custom way, for example according to some user name and password or IP address and provide your own method to find the appropritate grid for the request.<br />

<!--  Updating instance  -->
<a name="Updating"></a>
<h5>Updating instance</h5>
If you have created instance and you only need to change some of its configuration settings (but not columns), you can use <b><a href="#UpdateGrid">UpdateGrid</a></b> function.<br />

<!--  Processing client's request  -->
<a name="Request"></a>
<h5>Processing client's request</h5>
When you have an index to TreeGrid instance, you can use next functions.<br />
You can response to three main client's request - to get body, to get one page and to update data. And two support requests to get exported data and to get changes.<br />

<!--Request GetBody-->
<a name="RequestGetBody"></a>
<h6>a) Request GetBody</h6>
Body is whole grid data. When used server paging, it does not contain content of any page - in this case contains only page descriptions, page names and fixed rows.<br />
Client requests body when<br />
  <div class="L1">
  a) document is loaded for first time<br />
  b) document is reloaded<br />
  c) used server paging and rows have been re-sorted<br />
  d) used server paging and filter has changed<br />
  e) used server paging and grouping has changed<br />
  f) used server paging and search has been done - <i>search feature is not supported by current version of TreeGrid server library.</i><br />
  </div>
To get body just return <b><a href="#GetBody">GetBody</a></b> function result.<br />

<!--Request GetPage-->
<a name="RequestGetPage"></a>
<h6>b) Request GetPage</h6>
Page is one page when used server paging. When used client paging, this request does not occur.<br />
Page is also children of parent row or group when used server child paging. When used client child paging, this request does not occur.<br />
Client request a page when page is displayed or parent row was expanded, and it was not downloaded yet.<br />
To get page just return <b><a href="#GetPage">GetPage</a></b> function result.<br />

<!--Request Update-->
<a name="RequestUpdate"></a>
<h6>c) Request Update</h6>
Save occurs when client changed some data and is sending them to server to update.<br /><br />

Call <b><a href="#Save">Save</a></b> function to update data to the instance.<br /> 
But you need to save changes also your original data store (database, file, etc.) by parsing the request XML and updating to your original store. See <a href="DataUpload.htm#XML">XML structure - upload</a>.<br /><br />

If there are more instances of TreeGrid for the table (more clients simultaneously read the same table) is good idea to permit just only client to change data to avoid access violation and data inconsistency. When the one chosen client changes data, call <b><a href="#Save">Save</a></b> for all opened instances of the grid. To get all the instances for update, call <a href="#FindGrids">FindGrids</a>, see also <a href="#Finding">Finding instance</a>.<br />
If there are more clients with write access to one document, you need to implement your own semaphores or another technique to avoid access violation.<br />

<!--Request GetExport-->
<a name="RequestGetExport"></a>
<h6>d) Request GetExport</h6>
This is request for all data to be exported in XLS file to download and open in Excel. It is sent, when user clicks to Export button on TreeGrid toolbar.<br />
To get exported data just return <a href="#GetExport">GetExport</a> function result.<br /> 
When exporting data to Excel, do not forget to set in HTTP response <b>ContentType</b> to "application/vnd.ms-excel" and <b>Content-Disposition</b> to "attachment; <tt>filename="export_file.xls"</tt>)<br />

<!--Request GetChanges-->
<a name="RequestGetChanges"></a>
<h6>e) Request GetChanges</h6>
When you set in your grid to check for updates feature (&lt;treegrid <a href="DataServerChanges.htm#Synchronizing">Check_</a>>), the grid periodically sends this request to server to find, if there is some update to the data.<br />
The changes can be marked by using <a href="#SaveEx">SaveEx</a> method instead of Save. This feature can be used, when database is frequently changing or if any other visitor(s) have write access to the data.<br />
To get chanegs just return <a href="#GetChanges">GetChanges</a> function result.<br />

<!--  Saving data back  -->
<a name="Saving"></a>
<h5>Saving data back</h5>
When data are changed by <b><a href="#RequestUpdate">Update</a></b> request or by you custom calling <b><a href="#UpdateGrid">UpdateGrid</a></b> function you will need save instance data back to you original storage.<br /> 
You can use function <b><a href="#SaveToFile">SaveToFile</a></b> to save data to disk or get data in string from function <b><a href="#GetData">GetData</a></b> and update it manually, for example to database.<br />
Or you can use <b><a href="#GetChanges">GetChanges</a></b> function to get all Update requests (if you used <a href="#SaveEx">SaveEx</a> function with <tt>Type==1</tt>) and parse and update them manually to database.<br />
Or you can just parse XML got in <a href="#RequestUpdate">Update</a> request and provide changes.<br />
Remember, the saved data are sorted by last used sorting and contains filter settings, but always all rows, not only filtered.<br /> 
When to update the original data depends on your needs. You can do after every Update request, after some time, or you can call your own request procedure when data is needed.<br />
Other way is to save all input data into grid instance and simultaneously to the original data store by parsing input XML string in <b><a href="#RequestUpdate">Update</a></b> request. See <a href="DataUpload.htm#XML">XML structure of Upload request</a>.
  
<!--Temporary saving-->
<a name="TempSaving"></a>
<h6>Temporary saving</h6>
You can use functions <b><a href="#SaveToFile">SaveToFile</a></b> and <b><a href="#GetData">GetData</a></b> to temporary save data to persistent storage when server service is restarted or to free memory. After data save you can delete the instance by <b><a href="#DeleteGrid">DeleteGrid</a></b> function. In next request you will to create the instance again. Pass saved data as first parameter to <b><a href="#CreateGrid">CreateGrid</a></b>.  

<!--  Special attributes  -->
<a name="Attributes"></a>
<h5>Special XML attributes</h5>
TreeGrid library accepts these attributes in input XML data:<br />
&lt;Cfg <b>Precision</b>> [4] - Rounding precision of all numbers in TreeGrid server, available values are 0 - 9.<br />
&lt;Cfg <b>MaxChildrenOffline</b>> [3] - In server child paging the children are served with the parent if their count is less or equal to this value.<br />
&lt;Cfg <b>ShowFocused</b>> [0] - If set to 1, it serves in body response all parents (expanded) of &lt;Cfg <b>Focused</b>> row.<br />
&lt;Cfg <b>ChangedParents</b>> [0] - If set to 1, <b>GetChanges</b> returns also all changed parents and root page of changed rows. Useful for updating aggregate calculation results  on client.<br />
&lt;Changes <b>Reload</b>="1"> - It is filled to <b>GetChanges</b> response if client should reload data to get all the newest data.<br /> 

<!-----------------------  Function reference  ------------------------>
<a name="Reference"></a>
<h3>Function reference</h3>

<!--  CreateGrid  -->
<a name="CreateGrid"></a>
<h5 style="color:blue;">CreateGrid</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>CreateGrid</b> (wchar_t *<b>Data</b>, wchar_t *<b>Layout</b>, wchar_t *<b>Defaults</b>, wchar_t *<b>Text</b>, wchar_t *<b>Bonus</b>, wchar_t *<b>Bonus2</b>);</tt></td></tr> 
<tr><td>C++</td><td><tt>int <b>CreateGridA</b> (char *<b>Data</b>, char *<b>Layout</b>, char *<b>Defaults</b>, char *<b>Text</b>, char *<b>Bonus</b>, char *<b>Bonus2</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>CreateGrid</b> (string <b>Data</b>, string <b>Layout</b>, string <b>Defaults</b>, string <b>Text</b>, string <b>Bonus</b>, string <b>Bonus2</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>CreateGrid</b> (ByVal <b>Data</b> As String, ByVal <b>Layout</b> As String, ByVal <b>Defaults</b> As String, ByVal <b>Text</b> As String, ByVal <b>Bonus</b> As String, ByVal <b>Bonus2</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGCreateGrid</b> (char* <b>Data</b>, char* <b>Layout</b>, char* <b>Defaults</b>, char *<b>Text</b>, char* <b>Bonus</b>, char *<b>Bonus2</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>CreateGrid</b> (String <b>Data</b>, String <b>Layout</b>, String <b>Defaults</b>, String <b>Text</b>, String <b>Bonus</b>, String <b>Bonus2</b>);</tt></td></tr>
</table><br />

Creates new grid instance from XML data in given files or strings. Returns grid index, that can be used in other functions.<br />
Input parameters can be XML string (first character must be '<b>&lt;</b>' or '<b>&amp;</b>') or XML file.<br />
Returns &lt;<b>0</b> for error (-<b>1</b> input file not found, -<b>2</b> file cannot be read, -<b>3</b> bad XML format)<br />
<b>Data</b> - required - the XML data rows. This is only data that can be saved back.<br />
<b>Layout</b> - can be NULL - grid layout (columns, definitions, configuration, ...)<br />
<b>Defaults</b> - can be NULL - grid defaults, usually <b><a href="Files.htm#DefaultsXml">Defaults.xml</a></b>. Remember, some default settings is always required.<br />
<b>Text</b> - can be NULL - grid text, usually <b><a href="Files.htm#TextXml">Text.xml</a></b>. In actual version is not used.<br />
<b>Bonus</b>, <b>Bonus2</b> - can be NULL - XML data in string, to change some settings<br />
Remember, if you pass XML file as parameter, you must give absolute path. Relative paths in this context are very problematic.<br />

<!--  UpdateGrid  -->
<a name="UpdateGrid"></a>
<h5>UpdateGrid</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>UpdateGrid</b> (int <b>Index</b>, wchar_t *<b>Bonus</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>UpdateGridA</b> (int <b>Index</b>, char *<b>Bonus</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>UpdateGrid</b> (int <b>Index</b>, string <b>Bonus</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>UpdateGrid</b> (ByVal <b>Index</b> As Integer, ByVal <b>Bonus</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGUpdateGrid</b> (int <b>Index</b>, char *<b>Bonus</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>UpdateGrid</b> (int <b>Index</b>, String <b>Bonus</b>);</tt></td></tr>
</table><br />

Updates Grid settings by XML string <b>Bonus</b>.<br />
Returns <b>0</b> OK, -<b>1</b> grid not found, -<b>3</b> bad input XML.<br />
Use this function to modify some grid settings, not to saving changes to data. For saving changes use <a href="#Save">Save</a> or <a href="#SaveEx">SaveEx</a> function.<br />

<!--  FindGrid  -->
<a name="FindGrid"></a>
<h5>FindGrid</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>FindGrid</b> (wchar_t *<b>Cfg</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>FindGridA</b> (char *<b>Cfg</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>FindGrid</b> (string <b>Cfg</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>FindGrid</b> (ByVal <b>Cfg</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGFindGrid</b> (char *<b>Cfg</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>FindGrid</b> (String <b>Cfg</b>);</tt></td></tr>
</table><br />

Looks for grid with the same Session attribute (<tt>&lt;Grid>&lt;IO <a href="DataCommunication.htm#IOSession">Session</a>='???'/>&lt;/Grid></tt>) as in given <b>Cfg</b> string.<br />
Session attribute can be set in functions CreateGrid, UpdateGrid, GetBody, GetPage, Save.<br />
If Session attribute is not set, it is by default the grid index returned from CreateGrid.<br />
By Session should be the grid instance fully identified. The Session attribute (if set) is returned in every TreeGrid request.<br />
Returns grid index or -<b>1</b> grid not found, -<b>2</b> no &lt;IO> Session attribute set in Cfg or no grid found for the Session, -<b>3</b> bad input XML.<br />
The -<b>2</b> is returned if the grid instance was already freed from memory. It happens especially in PHP when used as CGI.<br />

<!--  FindGrids  -->
<a name="FindGrids"></a>
<h5>FindGrids</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>FindGrids</b> (int *<b>Indexes</b>, int <b>Max</b>, wchar_t *<b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>FindGridsA</b> (int *<b>Indexes</b>, int <b>Max</b>, char *<b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>FindGrids</b> (IntPtr <b>Indexes</b>, int <b>Max</b>, string <b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>FindGrids</b> (ByVal <b>Indexes</b> As IntPtr, ByVal <b>Max</b> As Integer, ByVal <b>Cfg</b> As String, ByVal <b>Seconds</b> As Integer, ByVal <b>Type</b> As Integer) As Integer</tt></td></tr>
<tr><td>PHP</td><td><i>use <a href="#FindGridsStr">FindGridsStr</a> instead</i></td></tr>
<tr><td>Java</td><td><tt>int <b>FindGrids</b> (int[] <b>Indexes</b>, int <b>Max</b>, string <b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
</table><br />

Looks for grids with the same attribute values in &lt;Cfg> tag as in <b>Cfg</b> parameter. So you should fill to <b>Cfg</b> parameter only those attributes according to you want to search.<br />
<b>Indexes</b> is array of integers filled by found indexes. <b>Indexes</b> can be null to get only count of grids.<br />
<b>Max</b> is maximum count of indexes to fill to <b>Indexes</b> array.<br />
<b>Cfg</b> is full Grids XML data with &lt;Cfg> tag like "<tt>&lt;Grid>&lt;Cfg MyAttr='xy'/>&lt;/Grid></tt>" to search grids according to.<br />
If <b>Seconds</b> is not 0 the function returns only grids older this count of seconds - the last access to grids was before this count of seconds.<br /> 
<b>Type</b> is reserved and should be 0.<br />
Returns count of found grids (count of indexes in <b>Indexes</b>) or -<b>3</b> for bad XML in Cfg.<br />
Use this function to get indexes from some group of grids marked by some (usually custom) attribute in &lt;Cfg> tag.<br />
Or use this function to get old (probably not used) grid instances to backup or delete them.<br />
New in version <b>2.0</b>.<br />

<!--  FindGridsStr  -->
<a name="FindGridsStr"></a>
<h5>FindGridsStr</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>char* <b>FindGridsStrA</b> (int <b>Max</b>, char *<b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>PHP</td><td><tt>char* <b>TGFindGridsStr</b> (int <b>Max</b>, char *<b>Cfg</b>, int <b>Seconds</b>, int <b>Type</b>);</tt></td></tr>
</table><br />

The same as <a href="#FindGrids">FindGrids</a>, but returns <b>Indexes</b> as comma separated string. If no index found, returns null.<br />
New in version <b>2.0</b>.<br />

<!--  GetSession  -->
<a name="GetSession"></a>
<h5>GetSession</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t* <b>GetSession</b> (wchar_t *<b>Cfg</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char* <b>GetSession A</b> (char *<b>Cfg</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetSession</b> (string <b>Cfg</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetSession</b> (ByVal <b>Cfg</b> As String) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char* <b>TGGetSession</b> (char *<b>Cfg</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetSession</b> (String <b>Cfg</b>);</tt></td></tr>
</table><br />

Returns value of &lt;IO Session> attribute from given XML string. If no session found returns null.<br />
Useful when the grid data are unloaded from memory and saved to disk or database according to Session id.<br />
New in version <b>3.0</b>.<br />

<!--  GetGridSession  -->
<a name="GetGridSession"></a>
<h5>GetGridSession</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t* <b>GetGridSession</b> (int Index);</tt></td></tr>
<tr><td>C++</td><td><tt>char* <b>GetGridSessionA</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetGridSession</b> (int Index);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetGridSession</b> (ByVal <b>Index</b> As Integer) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char* <b>TGGetGridSession</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetGridSession</b> (int <b>Index</b>);</tt></td></tr>
</table><br />

Returns actual value of &lt;IO Session> attribute in given grid instance. If no session found returns null.<br />
Useful when the grid data are unloaded from memory and saved to disk or database according to Session id.<br />
New in version <b>3.0</b>.<br />

<!--  DeleteGrid  -->
<a name="DeleteGrid"></a>
<h5>DeleteGrid</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>DeleteGrid</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>DeleteGrid</b> (int Index);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>DeleteGrid</b> (ByVal <b>Index</b> As Integer) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGDeleteGrid</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>DeleteGrid</b> (int <b>Index</b>);</tt></td></tr>
</table><br />

Deletes the grid. Frees all its resources.<br /> 
Returns <b>0</b> OK, -<b>1</b> grid not found.<br />

<!--  Clear  -->
<a name="Clear"></a>
<h5>Clear</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>void <b>Clear</b> ( );</tt></td></tr>
<tr><td>C#</td><td><tt>void <b>Clear</b> ( );</tt></td></tr>
<tr><td>VB</td><td><tt>Sub <b>Clear</b> ( )</tt></td></tr>
<tr><td>PHP</td><td><tt>void <b>TGClear</b> ( );</tt></td></tr>
<tr><td>Java</td><td><tt>void <b>Clear</b> ( );</tt></td></tr>
</table><br />

Deletes all grids. Frees all resources.<br />
But remember, this does not unlock the dll file. To unlock it, you must call FreeLibrary ( ), but only if it was loaded dynamically (in ASP.NET or Java it is not possible).<br />

<!--  GetBody  -->
<a name="GetBody"></a>
<h5 style="color:blue;" >GetBody</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetBody</b> (int <b>Index</b>, wchar_t *<b>Cfg</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetBodyA</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetBody</b> (int <b>Index</b>, string <b>Cfg</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetBody</b> (ByVal <b>Index</b> As Integer, ByVal <b>Cfg</b> As String) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetBody</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetBody</b> (int <b>Index</b>, String <b>Cfg</b>);</tt></td></tr>
</table><br />

Returns main data for TreeGrid in XML string. If <tt>Paging==3</tt>, returns only pages (tags &lt;B>) without any child tags &lt;I>. For error returns null.<br />
<b>Cfg</b> - required - XML string with TreeGrid configuration - sorting and filters.<br />
Function also modifies main data.<br />

<!--  GetPage  -->
<a name="GetPage"></a>
<h5 style="color:blue;" >GetPage</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetPage</b> (int <b>Index</b>, wchar_t *<b>Cfg</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetPageA</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetPage</b> (int <b>Index</b>, string <b>Cfg</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetPage</b> (ByVal <b>Index</b> As Integer, ByVal <b>Cfg</b> As String) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetPage</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetPage</b> (int <b>Index</b>, String <b>Cfg</b>);</tt></td></tr>
</table><br />

Returns data for one page if <tt>Paging==3</tt> or children of row if <tt>ChildPaging==3</tt>.<br />
<b>Cfg</b> - required - XML string with requested page (identified by position) or row (identified by id) and with TreeGrid configuration - sorting and filters.<br />
<b>Cfg</b> contains requested page or row identification. Both requests are set by &lt;B> tag, page is identified by <b><a href="PagingServer.htm#BPos">Pos</a></b> attribute and row by <b><a href="RowId.htm#Iid">id</a></b> attribute optionally with <b><a href="PagingServer.htm#BPos">Pos</a></b> attribute for particular child part.<br />
<b>Cfg</b> also contains setting for sorting and filters. If these settings do not correspond to settings in last call <a href="#GetBody">GetBody</a>, the GetPage returns NULL.<br />
Returns null if no page or row is requested or the requested page or row is not found.<br />
Does not return rows marked as Filtered. Returns all cells with values set.<br />
Function does not modify main data (only if configuration changes).<br />

<!--  Save  -->
<a name="Save"></a>
<h5 style="color:blue;" >Save</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>Save</b> (int <b>Index</b>, wchar_t *<b>Input</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>SaveA</b> (int <b>Index</b>, char * <b>Input</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>Save</b> (int <b>Index</b>, string <b>Input</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>Save</b> (ByVal <b>Index</b> As Integer, ByVal <b>Input</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGSave</b> (int <b>Index</b>, char * <b>Input</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>Save</b> (int <b>Index</b>, String <b>Input</b>);</tt></td></tr>
</table><br />

Saves changes to main data. The same as <a href="#SaveEx">SaveEx</a> function with <tt>Type = 0</tt>.<br />
<b>Input</b> is XML string with changed rows. It contains rows that have been added, deleted, moved or changed. Function irreversibly modifies main data.<br />
Returns <b>0</b> OK, -<b>3</b> bad Input XML, ><b>0</b> number of rows not successfully saved.<br />

<!--  SaveEx  -->
<a name="SaveEx"></a>
<h5>SaveEx</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>SaveEx</b> (int <b>Index</b>, wchar_t *<b>Input</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>SaveExA</b> (int <b>Index</b>, char * <b>Input</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>SaveEx</b> (int <b>Index</b>, string <b>Input</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>SaveEx</b> (ByVal <b>Index</b> As Integer, ByVal <b>Input</b> As String, ByVal <b>Type</b> As Integer) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGSaveEx</b> (int <b>Index</b>, char * <b>Input</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>SaveEx</b> (int <b>Index</b>, String <b>Input</b>, int <b>Type</b>);</tt></td></tr>
</table><br />

Saves changes to main data.<br />
<b>Input</b> is XML string with changed rows. It contains rows that have been added, deleted, moved or changed. Function irreversibly modifies main data.<br />
If <b>Type</b> = 1 it remembers the changes to be got by <a href="#GetChanges">GetChanges</a> function. More changes are merged together.<br />
	<div class="L1">
  Type = 1 is usually set for all other grid instances except the grid instance the changes are coming from.<br />
  </div>
If <b>Type</b> = 2 it remembers the id modifications if new id collided with some id stored in data.<br />
	<div class="L1">
	Type = 2 is usually set for the grid instance the changes are coming from.<br />
	This setting has sense only when more users have rights to add new rows that can cause id colliding.<br />
  </div>
Returns <b>0</b> OK, -<b>3</b> bad Input XML, ><b>0</b> number of rows not successfully saved.<br />
New in version <b>2.0</b>.<br />

<!--  GetChanges  -->
<a name="GetChanges"></a>
<h5>GetChanges</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetChanges</b> (int <b>Index</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetChangesA</b> (int <b>Index</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetChanges</b> (int <b>Index</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetChanges</b> (ByVal <b>Index</b> As Integer, ByVal <b>Type</b> As Integer) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetChanges</b> (int <b>Index</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetChanges</b> (int <b>Index</b>, int <b>Type</b>);</tt></td></tr>
</table><br />

Returns all changes done by <a href="#SaveEx">SaveEx</a> function with <tt>Type=1</tt>. Returns only &lt;Changes> tag without parent &lt;Grid> tag. Returns null if there are no pending changes.<br />
If <b>Type</b>=1, it clears all returned changes, so you will not get them in next call of GetChanges. Remember, it never modifies the data.<br />
You can use this function to get changes and return them to client when <a href="DataServerChanges.htm#Synchronizing">checking for updates</a> function is used or you can get and parse them and store changes to database instead of use <a href="#GetData">GetData</a> function.<br />
New in version <b>2.0</b>.<br />

<!--  GetCells  -->
<a name="GetCells"></a>
<h5>GetCells</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetCells</b> (int Index, wchar_t *<b>Row</b>, wchar_t *<b>Col</b>, int <b>Type</b>, wchar_t *<b>Param</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetCellsA</b>  (int <b>Index</b>, char *<b>Row</b>, char *<b>Col</b>, int <b>Type</b>, char *<b>Param</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetCells</b> (int <b>Index</b>, string <b>Row</b>, string <b>Col</b>, int <b>Type</b>, string <b>Param</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetCells</b> (ByVal <b>Index</b> As Integer, ByVal <b>Row</b> As String, ByVal <b>Col</b> As String, ByVal <b>Type</b> As Integer, ByVal <b>Param</b> As String) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetCells</b> (int <b>Index</b>, char *<b>Row</b>, char *<b>Col</b>, int <b>Type</b>, char *<b>Param</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetCells</b> (int <b>Index</b>, String <b>Row</b>, String <b>Col</b>, int <b>Type</b>, String <b>Param</b>);</tt></td></tr>
</table><br />

Returns values from selected cells. Returns all data in one string, separated by the first character in <b>Param</b>.<br />
<b>Row</b> - a row id, can be null, see <b>Type</b><br />
<b>Col</b> - required - from this column will be the cells returned. In fact the <b>Col</b> can be any row or cell attribute name.<br />
<b>Type</b> - required - which cells will be returned for the given <b>Row</b> and other options<br />
  <div class="L1">
  <table>
  <tr><td style="width:100px">(1-2. bit, &3)</td><td><b>0</b> - returns only one given cell [Row,Col]</td></tr>
  <tr><td></td><td><b>1</b> - returns values from all sibling rows, including the <b>Row</b>.</td></tr>
  <tr><td></td><td><b>2</b> - returns values from all variable rows, the <b>Row</b> is ignored.</td></tr>
  <tr><td></td><td><b>3</b> - returns values from all variable and fixed rows, the <b>Row</b> is ignored.</td></tr>
  <tr><td>(3. bit, &4)</td><td><b>4</b> - the result is formatted according to Format/Enum attributes, only for Enum and Date types</td></tr>
  <tr><td>(4-5. bit, &24)</td><td><b>8</b> - the values will be sorted as numbers</td></tr>
  <tr><td></td><td><b>16</b> - the values will be sorted as strings, case insensitive</td></tr>
  <tr><td></td><td><b>24</b> - the values will be sorted as strings, case sensitive</td></tr>
  <tr><td>(6.bit, &32)</td><td><b>32</b> - only one value from the same values (according to the sorting) will be listed</td></tr>
  <tr><td>(7.bit, &64)</td><td><b>64</b> - no empty value(s)</td></tr>                  
  </table>
  </div>
<b>Param</b> - its first character is used to separate the values in the returned string. If it is empty, the '|' is used.<br />
  <div class="L1"><b>Param</b> can also contain "|name|value" to return only rows their attribute name is equal to value.</div>  
<i>For example <tt>GetCells(0,"123","A",1,"!Visible!1")</tt> returns all siblings of the row with id "123", only visible rows, values from column 'A'.<br /> 
The result can be for example <tt>"!45!2.4!66!12"</tt> (it is separated by the '!', because it was set as the first character in Param).</i><br />
It can be used especially to get string for Defaults list.<br />
New in version <b>3.4</b>.<br />

<!--  GetExport  -->
<a name="GetExport"></a>
<h5 style="color:blue">GetExport</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetExport</b> (int <b>Index</b>, wchar_t *<b>Cfg</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetExportA</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetExport</b> (int <b>Index</b>, string <b>Cfg</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetExport</b> (ByVal <b>Index</b> As Integer, ByVal <b>Cfg</b> As String) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetExport</b> (int <b>Index</b>, char *<b>Cfg</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetExport</b> (int <b>Index</b>, String <b>Cfg</b>);</tt></td></tr>
</table><br />

Returns data exported to MS Excel. It returns data in HTML with specific formatting for Excel. Returns null for error.<br />
<b>Cfg</b> - required - XML string with list all columns with position, width and visibility.<br />
New in version <b>3.0</b>.<br />

<!--  SaveToFile  -->
<a name="SaveToFile"></a>
<h5>SaveToFile</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>SaveToFile</b> (int <b>Index</b>, wchar_t *<b>FileName</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>SaveToFileA</b> (int <b>Index</b>, char * <b>FileName</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>SaveToFile</b> (int <b>Index</b>, string <b>FileName</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>SaveToFile</b> (ByVal <b>Index</b> As Integer, ByVal <b>FileName</b> As String, ByVal <b>Type</b> As Integer) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGSaveToFile</b> (int <b>Index</b>, char * <b>FileName</b>, int <b>Type</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>SaveToFile</b> (int <b>Index</b>, String <b>FileName</b>, int <b>Type</b>);</tt></td></tr>
</table><br />

Saves data to file. Saves all rows, include all attributes (such Filtered). Saves in last state (sorting, filters, calculations).<br />
<b>FileName</b> - required - FileName with path to save to.<br />
<b>Type</b> - required (default = <b>28</b> = UTF8 + session + cfg + body) - bit array:<br />
  <div class="L1">
  1.bit (&1) - data format - 0 - UTF8, 1 - Unicode.<br />
  2.bit (&2) - reserved<br />
  3.bit (&4) - save session (&lt;IO Session> attribute)<br />
  4.bit (&8) - save configuration (sorting, grouping, search, filters)<br />
  5.bit (&16) - save &lt;Body> tag<br />
  6.bit (&32) - save &lt;Head> and &lt;Foot> tags<br />
  7.bit (&64) - save all other tags than &lt;Body>, &lt;Head>, &lt;Foot>. It saves also configuration and session.<br />
  </div>
Returns <b>0</b> OK, -<b>1</b> file cannot be created, -<b>2</b> file cannot be written, -<b>3</b> corrupted data<br />

<!--  GetData  -->
<a name="GetData"></a>
<h5>GetData</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetData</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetDataA</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetData</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetData</b> (ByVal <b>Index</b> As Integer) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetData</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetData</b> (int <b>Index</b>);</tt></td></tr>
</table><br />

Returns all data in string. This is the same as function <a href="#SaveToFile">SaveToFile</a>, but always returns unicode (or ...<b>A</b> UTF8) string. Returns null for error.<br />

<!--  GetLastId  -->
<a name="GetLastId"></a>
<h5>GetLastId</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>GetLastId</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>GetLastIdA</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>GetLastId</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>GetLastId</b> (ByVal <b>Index</b> As Integer) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGGetLastId</b> (int <b>Index</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>GetLastId</b> (int <b>Index</b>);</tt></td></tr>
</table><br />

Returns last (highest) id in grid. Use this function to get the last id after saving changes by <a href="#Save">Save</a> function when copying collapsed rows with children is permitted.<br />
You should return this last id in <tt>&lt;Cfg LastId='...'/></tt> back to grid after successful save to update <a href="RowId.htm#CfgLastId">LastId</a> property on client.<br />
Copying collapsed rows means that user can copy rows with not loaded children => copying is done only on server by <a href="RowAdd.htm#ICopy">Copy</a> attribute.<br />
Returns null for error.<br />
New in version <b>2.0</b>.<br />

<!--  SetGridLocale  -->
<a name="SetGridLocale"></a>
<h5>SetGridLocale</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>SetGridLocale</b> (int <b>Index</b>, wchar_t *<b>Locale</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>SetGridLocaleA</b> (int <b>Index</b>, char * <b>Locale</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>SetGridLocale</b> (int <b>Index</b>, string <b>Locale</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>SetGridLocale</b> (ByVal <b>Index</b> As Integer, ByVal <b>Locale</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGSetGridLocale</b> (int <b>Index</b>, char * <b>Locale</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>SetGridLocale</b> (int <b>Index</b>, String <b>Locale</b>);</tt></td></tr>
</table><br />

Chooses language for internationalization when comparing strings for sorting, filtering and grouping.<br />
<i>Index</i> is index of given grid. Every grid instance can have its own locale settings.<br />
<i>Locale</i> is name of language like "french", "german", "czech". For name reference see <a href="http://msdn2.microsoft.com/en-us/library/39cwe7zf(VS.80).aspx">http://msdn2.microsoft.com/en-us/library/39cwe7zf(VS.80).aspx</a>.<br />
Locale can also specify regional sub language if different, in this schema: <tt>"lang[_territory[.code_page]]"</tt>,<br />
where <i>lang</i> is ISO 639 language code, <i>territory</i> is an ISO 3166 country code, and <i>code_page</i> is a character set or encoding identifier like ISO-8859-1 or UTF-8.<br />
For standard English language don't call this function, it slows down strings comparing.<br />
Strings are compared according to given locale only if SortType / GroupType / FilterType has set second bit (&2) for locale comparing.<br />
<b style="color:red">!</b> Attention, the locale comparing is always <i><b>case insensitive</b></i> !<br />
New in version 3.0.<br />

<!--  EnterRead, LeaveRead, EnterWrite, LeaveWrite  -->
<a name="SetGridLocale"></a>
<h5>EnterRead, LeaveRead, EnterWrite, LeaveWrite</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>void <b>EnterRead</b> ( ); void <b>LeaveRead</b> ( ); void <b>EnterWrite</b> ( ); void <b>LeaveWrite</b> ( );</tt></td></tr>
<tr><td>C#</td><td><tt>void <b>EnterRead</b> ( ); void <b>LeaveRead</b> ( ); void <b>EnterWrite</b> ( ); void <b>LeaveWrite</b> ( );</tt></td></tr>
<tr><td>VB</td><td><tt>Sub <b>EnterRead</b> ( ) : Sub <b>LeaveRead</b> ( ) : Sub <b>EnterWrite</b> ( ) : Sub <b>LeaveWrite</b> ( );</tt></td></tr>
<tr><td>PHP</td><td><tt>void <b>TGEnterRead</b> ( ); void <b>TGLeaveRead</b> ( ); void <b>TGEnterWrite</b> ( ); void <b>TGLeaveWrite</b> ( );</tt></td></tr>
<tr><td>Java</td><td><tt>void <b>EnterRead</b> ( ); void <b>LeaveRead</b> ( ); void <b>EnterWrite</b> ( ); void <b>LeaveWrite</b> ( );</tt></td></tr>
</table><br />

Critical section<br />
Use critical sections if you need to call more than one function without interference with other threads.<br /> 
All TreeGrid functions itself are thread safe and you don't need to use critical section for them.<br />
This critical section is usual <b>Multi read exclusive write synchronizer</b>. It is <b>not reentrant</b> - you cannot call EnterWrite twice from one thread.<br />
For every EnterRead you must call LeaveRead and for every EnterWrite you must call LeaveWrite.<br />
EnterWrite waits for all threads to finish reading or writing. There can be only one thread that writes at a time.<br />
EnterRead waits for all threads to finish writing. There can be more threads that read at a time.<br />
These functions are in fact independent on grids and can be used everywhere.<br />
New in version <b>3.0</b>.<br /><br />

<p style="text-align:center"><i><b>Other function</b></i></p>

<!--  LockLibrary  -->
<a name="LockLibrary"></a>
<h5>LockLibrary</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>LockLibrary</b> (wchar_t *<b>LibName</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>LockLibrary</b> (wchar_t *<b>LibName</b>);</tt></td></tr>
</table><br />

Locks library in memory to not be unloaded after the server script frees its handle. Use only in non-standard server script environment.<br />
<b>LibName</b> is full path to TreeGrid.dll.<br />
The function can be called more times, it locks library only once.<br />
Returns <b>1</b> - success, <b>0</b> - error, -<b>1</b> library already locked<br />
New in version <b>2.0</b>.<br />

<!--  UnlockLibrary  -->
<a name=""></a>
<h5>UnlockLibrary</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>UnlockLibrary</b> ( );</tt></td></tr>
</table><br />

Unlocks library previously locked by <b>LockLibrary</b> function.<br />
Returns <b>1</b> - success, <b>0</b> - error, -<b>1</b> library is not locked<br />
New in version <b>2.0</b>.<br />

<!--  FreeString  -->
<a name="FreeString"></a>
<h5>FreeString</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>void FreeString (wchar_t *Str);</tt></td></tr>
<tr><td>C++</td><td><tt>void FreeStringA (char *Str);</tt></td></tr>
</table>
Frees allocated string if calling environment cannot do this itself. Use it for all strings you got by TreeGrid functions.<br />
In standard server side environments like .NET, Java or PHP you don't need to (you must not) use this function.<br /><br />

<p style="text-align:center"><i><b>Debugging functions</b></i></p>

<strong>!</strong> <i>These functions are available only in debug version of TreeGrid.dll/so (<b>TreeGridDbg.dll / TreeGridDbg.so</b>).</i><br />

<!--  SetDebug  -->
<a name="SetDebug"></a>
<h5>SetDebug</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>int <b>SetDebug</b> (int <b>Level</b>, wchar_t *<b>FileName</b>);</tt></td></tr>
<tr><td>C++</td><td><tt>int <b>SetDebugA</b> (int <b>Level</b>, char * <b>FileName</b>);</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern int <b>SetDebug</b> (int <b>Level</b>, string <b>FileName</b>);</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>SetDebug</b> (ByVal <b>Level</b> As Integer, ByVal <b>FileName</b> As String) As Integer</tt></td></tr>
<tr><td>PHP</td><td><tt>int <b>TGSetDebug</b> (int <b>Level</b>, char * <b>FileName</b>);</tt></td></tr>
<tr><td>Java</td><td><tt>int <b>SetDebug</b> (int <b>Level</b>, String <b>FileName</b>);</tt></td></tr>
</table><br />

Sets debugging path and level of logs.<br />
<b>Level</b> is binary array and controls what will be logged: Default is <b>3</b>.<br />
  <div class="L1">
  1. bit (&1) - last error is stored and can be accessed by <a href="#LastError">LastError</a> function<br />
  2. bit (&2) - every global function called is logged with all its input parameters to file <i>FileName</i><b>G</b>_<i>Index</i>.log,<br /> 
    <div class="L1">
    where <i>FileName</i> is given <b>FileName</b>, <i>Index</i> is grid instance index, for functions without index is Index set as 'xxxx'<br />
    </div>
  3. bit (&4) - many information is logged to file FileNameT_Id.log,<br />
    <div class="L1">
    where <i>FileName</i> is given <b>FileName</b>, <i>Id</i> is global thread id that called the function<br />
    <b style="color:red;">!</b> Setting this bit can slow down the library and sometimes also crash it.<br />
    </div>
  4. bit (&8) - logs all the global called functions (by 2.bit) the one file with Index set as 'xxxx'.<br />
  </div>
<b>FileName</b> is only partial file name without extension. It can be also only directory path, but with ending '\' or '/'.<br />
Default <b>FileName</b> value is "c:\\treegrid\\log_" on Windows and "/tmp/treegrid/log_" on Linux.<br />
<b style="color:red;">!</b> The web server process must have rights to write to the directory where <b>FileName</b> resides and must have rights to create new files here.<br />
Returns <b>0</b> OK, -<b>1</b> Called in non debug DLL/SO, -<b>2</b> to file cannot be written<br />
New in version <b>3.0</b>.<br />

<!--  LastError  -->
<a name="LastError"></a>
<h5>LastError</h5>
<table>
<tr><td style="width:50px;">C++</td><td><tt>wchar_t * <b>LastError</b> ( );</tt></td></tr>
<tr><td>C++</td><td><tt>char * <b>LastErrorA</b> ( );</tt></td></tr>
<tr><td>C#</td><td><tt>public static extern string <b>LastError</b> ( );</tt></td></tr>
<tr><td>VB</td><td><tt>Function <b>LastError</b> ( ) As String</tt></td></tr>
<tr><td>PHP</td><td><tt>char * <b>TGLastError</b> ( );</tt></td></tr>
<tr><td>Java</td><td><tt>String <b>LastError</b> ( );</tt></td></tr>
</table><br />
  
Returns last error string message if any function returned error code. The last error is always cleared by calling any TreeGrid function.<br /> 
New in version <b>1.2</b>.<br />
In version <b>3.0</b> moved to debug version. In non-debug version returns always null.<br />

<!-----------------------  Calculations  ------------------------>
<a name="Calculations"></a>
<h3>Calculations</h3>
TreeGrid server is written in C++ and therefore you cannot use all JavaScript code in formulas calculated on server as you can do if formula is calculated on client.<br />
All names and keywords are case-sensitive.<br />
Default rounding precision of all numbers in TreeGrid server is 4 digits. It can be changed by <tt>&lt;Cfg Precision=''/></tt>, available values are 0 - 9.<br /><br />

<!--Operators-->
<a name="Operators"></a>
<h6>Operators <span style="font-weight:normal;">(sorted by priority):</span></h6>
  <div class="L2">
  <b style="color:blue;">!</b> (logical negation) <b style="color:blue;">~</b> (binary negation) <b style="color:blue;">-</b> (unary minus)<br />
  <b style="color:blue;">*</b> (multiplication) <b style="color:blue;">/</b> (division) <b style="color:blue;">%</b> (modulo)<br />
  <b style="color:blue;">+</b> (addition, number + number = number, number + string = string) <b style="color:blue;">-</b> (subtraction)<br />
  <b style="color:blue;">&lt;</b> (less then) <b style="color:blue;">&lt;=</b> (less or equal) <b style="color:blue;">></b> (greater then) <b style="color:blue;">>=</b> (greater or equal)<br />
  <b style="color:blue;">==</b> (equal) <b style="color:blue;">!=</b> (not equal)<br />
  <b style="color:blue;">&amp;</b> (binary AND)<br />
  <b style="color:blue;">^</b> (binary XOR)<br />
  <b style="color:blue;">|</b> (binary OR)<br />
  <b style="color:blue;">&amp;&amp;</b> (logical AND)<br />
  <b style="color:blue;">||</b> (logical OR)<br />
  <b style="color:blue;">?:</b> (conditional ternary operator => a ? b : c => if(a) return b; else return c; )<br />
  <b style="color:blue;">,</b> (comma, separates parameters in functions)<br />
  </div>

<!--Constants-->
<a name="Constants"></a>
<h6>Constants:</h6>
  <div class="L2">
  <b style="color:blue;">number</b> (floating point number, always starts with digit '0' - '9')<br />
  <b style="color:blue;">string</b> (any characters in quotes " " or apostrophes ' ', the string cannot contain enclosing quote or apostrophe)<br />
  </div>
  
<!--Identifiers-->
<a name="Identifiers"></a>
<h6>Identifiers:</h6>
  <div class="L2">
  <b style="color:blue;">ident</b> (any string without quotations, starting with letter ('a' - 'z', 'A' - 'Z') or underscore '_', can contain these characters and letters '0' - '9')<br />
    <div class="L2">
    This <i><b>ident</b></i> returns value from actual row from column named <i><b>ident</b></i>.<br />
    </div>
  <b style="color:blue;">func</b> (any ident followed by left parenthesis '(', comma separated parameters and right parenthesis ')' ).<br />
    <div class="L2">
    Parameters can contain expression, except aggregate functions in fixed rows (fixed rows are calculated in special way due paging).<br />
		This <i><b>func</b></i> returns value the function calculated.<br />  
    </div>
  </div>
  
<!--Identifiers-->
<a name="Functions"></a>
<h6>Function:</h6>
  <div class="L2">
  <table>
  <tr><td style="width:180px;"><b style="color:blue;">Get</b> (<b>Parent</b>, "<i>column</i>")</td><td>Returns the cell from column from immediate parent node, <b>Parent</b> is keyword without quotations, <i><b>column</b></i> must be quoted <u>constant</u>.</td></tr>
  <tr><td><b style="color:blue;">Get</b> (<i><b>id</b></i>, "<i>column</i>")</td><td>Returns the cell from column from row identified by <i><b>id</b></i>. <i><b>id</b></i> is an id attribute of row, without quotations, <i><b>column</b></i> must be quoted <u>constant</u>.</td></tr>
  <tr><td><b style="color:blue;">sum</b> ("<i>column</i>")</td><td>Sums all values in column or in actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">sumsq</b> ("<i>column</i>")</td><td>Sums all squares of values in column or in actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">count</b> ( )</td><td>Returns count of rows</td></tr>
  <tr><td><b style="color:blue;">counta</b> ("<i>column</i>")</td><td>Counts all non blank values in the column or in actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">countblank</b> ("<i>column</i>")</td><td>Counts all blank values in the column or in actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">product</b> ("<i>column</i>")</td><td>Multiplies all values in column or in actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">max</b> ("<i>column</i>")</td><td>Returns maximum value from the column or from actual column if called without parameter</td></tr>
  <tr><td><b style="color:blue;">min</b> ("<i>column</i>")</td><td>Returns minimum value from the column or from actual column if called without parameter</td></tr>
  </table>
  </div>
  
<!--Examples-->
<a name="Examples"></a>
<h6>Examples:</h6>
<tt>
&lt;I id = 'i' A = '5'>
  <div class="L2">
  &lt;I id='i1' A='10' B='5.5' C='yes' D='no'F = '<i><b>formula</b></i>'>
    <div class="L2">
    &lt;I id='i11' F='100' B='200'/><br />
    &lt;I id='i12' F='200'/><br />
    &lt;I id='i13' F='300' B='400'/><br />
    </div>
  &lt;/I>
  &lt;I id='i2' E='0.5'/>
  </div>
&lt;/I>
</tt><br />
<i>In these data let's have formula in second row (id='<b>i1</b>') for cell '<b>F</b>':</i><br />
<tt>
<table>
<tr><td style="width:250px;">A+B</td><td style="width:250px;">= 10+5.5</td><td>= 15.5</td></tr>
<tr><td>A+B+C</td><td>= 10 + 5.5 + "yes"</td><td>= 15.5yes</td></tr>
<tr><td>A+(B+C)+D</td><td>= 10 + (5.5 + "yes") + "no"</td><td>= 105.5yesno</td></tr>
<tr><td>A*B*C</td><td>= 10 * 5.5 * 0</td><td>= 0</td></tr>
<tr><td>A > 3 &amp;&amp; B+1 > 6 ? C : D</td><td>= 10 > 3 &amp;&amp; 5.5+1>6 ? "yes" : "no"</td><td>= yes</td></tr>
<tr><td>(!A+2) * -(B&amp;3)</td><td>= (!10 +2) * -(5.5&amp;3)</td><td>= -2   (!10 = 0,  5.5&amp;3=1)</td></tr>
<tr><td>"("+C+","+D+")</td><td>= "("+"yes"+","+"no"+")"</td><td>= (yes,no)</td></tr>
<tr><td>sum()</td><td>= 100+200+300</td><td>= 600</td></tr>
<tr><td>count() >= 3 ? sum("B") : D</td><td>= 3 >=3 ? 200+400 :  "no"</td><td>= 600</td></tr>
<tr><td>sum() * Get(i1,"E")</td><td>= (100+200+300) * 0.5</td><td>= 600</td></tr>
<tr><td>Get(Parent,"A") == Get(i11,"F")</td><td>= 5 == 100</td><td>= 0</td></tr>
</table>
</tt>
<br /><br /><br /><br /><br /><br /><br />
  
<i><b>Updates</b></i><br /><br />

<div style="font-size:85%;">
<b>2.0</b><br />
Added Compatibility section<br />
Added GetLastId function<br />
Added FindGrids function<br />
Added SaveEx and GetChanges functions<br />
Added LockLibrary and UnlockLibrary<br />
Rewritten PHP section<br /><br />

<b>3.0</b><br />
Added SetDebug function<br />
LastError function moved to newly created section Debugging functions<br />
Updated SaveToFile, parameter Type<br />
Added critical section function EnterRead,LeaveRead,EnterWrite,LeaveWrite<br />
Added SetGridLocale function<br />
Rewritten PHP section<br />
Added GetSession and GetGridSession functions<br />
Added functions sumsq, counta, countblank, product, max, min<br />
Rewritten section TreeGrid server concepts<br /><br />

<b>3.1</b><br />
Added compatibility with Range attribute for filters<br /><br />

<b>3.1.1</b><br />
Added &lt;Cfg Precision/> to set rounding precision of digits<br /><br />

<b>3.6</b><br />
Added &lt;Cfg ShowFocused ChangedParents MaxChildrenOffline> and &lt;Changes Reload="1"><br /><br />

</div>

</div>
</body>	
</html>